﻿using System;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using log4net.Core;
using Quiki.ExpressionParsers;
using Quiki.Templates;

namespace Quiki.DocumentGraphProcessors
{
    public class TemplateProcessor : IDocumentGraphProcessor
    {
        public TemplateProcessor(TemplatesRegistry templatesRegistry, ILogger logger)
        {
            this.templatesRegistry = templatesRegistry;
            this.logger = logger;
        }

        public void Execute(DocumentGraph documentGraph)
        {
            foreach (WikiDocument documentInfo in documentGraph.Documents.Values)
                ExpandDocument (documentInfo, documentGraph);
        }

        private void ExpandDocument (WikiDocument document, DocumentGraph documentGraph)
        {
            logger.PushContext(document.FileName);
            ExpandElement (document.RootElement, document, documentGraph);
            logger.PopContext();
        }

        [SuppressMessage ("Microsoft.Performance", "CA1800:DoNotCastUnnecessarily")]
        private void ExpandElement (WikiTextElement element, WikiDocument document, DocumentGraph documentGraph)
        {
            if (element is WikiTemplateElement)
            {
                WikiTemplateElement templateElement = (WikiTemplateElement)element;

                if (false == templatesRegistry.HasTemplate(templateElement.TemplateName))
                    logger.Log(Level.Warn, "Template '{0}' is not registered", templateElement.TemplateName);
                else
                    ExpandTemplate (templateElement, document, documentGraph);
            }

            for (int i = 0; i < element.ChildElements.Count; i++)
            {
                WikiTextElement childElement = element.ChildElements[i];
                ExpandElement (childElement, document, documentGraph);
            }
        }

        private void ExpandTemplate(
            WikiTemplateElement templateElement, 
            WikiDocument document, 
            DocumentGraph documentGraph)
        {
            IWikiTemplate template = templatesRegistry.GetTemplate(templateElement.TemplateName);
            template.Expand(templateElement, document, documentGraph);
        }

        private readonly TemplatesRegistry templatesRegistry;
        private readonly ILogger logger;
    }
}